package com.dyrnq.seckill.filter;

import com.dyrnq.seckill.controller.Result;
import com.dyrnq.seckill.exception.UnauthorizedException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;


public class ApiKeyFilter extends GenericFilterBean {

    public static final String APIKEY_HEADER_NAME = "X-API-KEY";
    private final String key;

    public ApiKeyFilter(String key) {
        this.key = key;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        try {
            resolveToken(httpServletRequest);
            filterChain.doFilter(servletRequest, servletResponse);
        } catch (Exception exp) {
            ObjectMapper objectMapper = new ObjectMapper();
            HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            httpResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            PrintWriter writer = httpResponse.getWriter();
            writer.print(objectMapper.writeValueAsString(Result.error(HttpServletResponse.SC_UNAUTHORIZED, exp.getMessage())));
            writer.flush();
            writer.close();
        }
    }

    private void resolveToken(HttpServletRequest request) {
        String apiKeyToken = request.getHeader(APIKEY_HEADER_NAME);
        // 如果没有消息头跳过校验
        if (apiKeyToken != null) {
            if (StringUtils.equalsIgnoreCase(apiKeyToken, key)) {
                request.setAttribute(APIKEY_HEADER_NAME, true);
            } else {
                throw new UnauthorizedException("Invalid API Key");
            }
        }
    }

}
